<template>
	<view class="wrap flex just-between" :class="{ wrapPadding: isMargin }">
		<block v-for="(numVal, index) in column" :key="numVal">
			<view
				class="cont-box"
				:style="{
					'--layout-width': 'calc((100% - ' + itemWidth + ') / ' + column + ')',
				}"
				:id="`cont_${index + 1}`"
			>
				<block v-for="(item, j) in flowData[`column_${index + 1}`]" :key="j">
					<view class="item">
						<image
							class="file"
							@click="onImage(j, index)"
							:src="item.file"
							mode="widthFix"
							lazy-load
							@load="imgLoad(item)"
							@error="imgError(item)"
						/>

						<view class="title f-30">
							{{ item.title }}
						</view>

						<view class="price-bg f-24"> ¥200 </view>
					</view>
				</block>
			</view>
		</block>
	</view>
</template>

<script>
	/**
	 * 这是一个瀑布流的列表
	 * @param {Number} column 列数 默认2个
	 * @param {Boolean} isMargin 最外层是否有左右的边距 防止引用此组件的视图已经设置了左右布局 间距过大 默认true
	 * @param {Array} goodsList 商品列表
	 * @example import waterfallFlow from "@/components/waterfallFlow/waterfallFlow.vue";
	 * @example <waterfallFlow :goodsList='' :column="3" :isMargin='false'></waterfallFlow>
	 * @example <waterfallFlow :goodsList=''></waterfallFlow>
	 */
	export default {
		props: {
			/**
			 * 一行显示几个
			 */
			column: {
				type: Number,
				default: 2,
			},
			/**
			 * 最外层是否显示左右的间距
			 */
			isMargin: {
				type: Boolean,
				default: true,
			},
			/**
			 * 列表
			 */
			goodsList: {
				type: Array,
				default: [],
				require: true,
			},
		},
		data() {
			return {
				flowData: {},
				itemWidth: "",
			};
		},
		created() {
			/* 初始化每一列的数据 */
			for (let i = 1; i <= this.column; i++) {
				this.$set(this.flowData, `column_${i}`, []);
			}
		},
		mounted() {
			this.itemWidth = this.$filters.rpxToPx(20 * (this.column - 1));
			this.$nextTick(() => {
				this.initValue(0);
			});
		},
		methods: {
			/**
			 * 获取最小的对象
			 */
			getMinObject(list, type) {
				let m = list[0][type];
				let mo = list[0];
				for (let i = list.length - 1; i >= 0; i--) {
					if (list[i][type] < m) m = list[i][type];
				}
				mo = list.filter((i) => i[type] === m);
				return mo[0];
			},
			/**
			 * 计算每列的高度
			 */
			getMinColumnHeight() {
				return new Promise((resolve) => {
					const heightArr = [];
					for (let i = 1; i <= this.column; i++) {
						let query = uni.createSelectorQuery();
						query.in(this);
						query.select(`#cont_${i}`).boundingClientRect((res) => {
							heightArr.push({
								column: i,
								height: res.height,
							});
						});
						query.exec((res) => {
							if (this.column <= heightArr.length) {
								resolve(this.getMinObject(heightArr, "height"));
							}
						});
					}
				});
			},
			/**
			 * 初始化瀑布流数据
			 */
			async initValue(i) {
				if (i >= this.goodsList.length) return false;
				const minHeightRes = await this.getMinColumnHeight();
				this.flowData[`column_${minHeightRes.column}`].push({
					...this.goodsList[i],
					index: i,
				});
				// this.initValue(i + 1); // 加载下一条数据
			},
			/**
			 * 图片加载完成
			 */
			imgLoad(item) {
				// console.log("图片加载完成", index);
				const i = item.index;
				this.initValue(i + 1); // 加载下一条数据
			},
			/**
			 * 图片加载失败
			 */
			imgError(item) {
				// console.log("图片加载失败", index);
				const i = item.index;
				this.initValue(i + 1); // 加载下一条数据
			},

			/**
			 * 预览图片
			 */
			onImage(j, index) {
				const list = this.flowData[`column_${index + 1}`];
				const item = list[j];
				console.log("AAAAA", item);
			},
		},
	};
</script>

<style lang="scss" scoped>
	.wrap {
		padding: 20rpx 0;
		width: 100%;
		box-sizing: border-box;
		background-color: #f6f6b2;
		overflow: hidden;
	}

	.wrapPadding {
		padding-left: 20rpx !important;
		padding-right: 20rpx !important;
	}

	.cont-box {
		width: var(--layout-width);
		float: left;
		height: fit-content;

		.item {
			margin-bottom: 20rpx;
			border-radius: 10rpx;
			padding: 20rpx;
			width: 100%;
			box-sizing: border-box;
			box-shadow: 0rpx 3rpx 6rpx rgba(0, 46, 37, 0.08);
			background: white;

			.file {
				border-radius: 10rpx;
				width: 100%;
			}

			.title {
				margin-top: 20rpx;
				line-height: 40rpx;
				color: #333;
			}

			.price-bg {
				margin-top: 20rpx;
				color: $theme-color;
			}
		}
	}
</style>
